<template>
  <a-spin :spinning="loading">
    <div class="blog_edit_div">
      <!-- 返回头部 -->
      <a-back-top/>
      <!-- 页头 -->
      <div class="edit_header">
        <a-tooltip placement="right">
          <template #title>
            <span>返回主页</span>
          </template>
          <router-link to="/home">
            <a-avatar :size="35" src="favicon.ico"/>
          </router-link>
        </a-tooltip>
        <a-input v-model:value="blog.title" placeholder="输入博客标题..." :maxlength="50"/>
        <a-button type="default" size="large" @click="back">返回</a-button>
        <!-- 发布气泡框 -->
        <a-popover v-model:visible="postPopoverVisible" trigger="click" placement="bottomRight">
          <template #title>
            <span class="post_popover_title">发布博客</span>
          </template>
          <template #content>
            <div class="post_popover_content">
              <a-divider orientation="right">分类</a-divider>
              <div class="post_popover_content_row">
                <a-select v-model:value="blog.classificationId">
                  <a-select-option v-for="classification in classificationOptions" :key="classification.id">
                    {{ classification.name }}
                  </a-select-option>
                </a-select>
                <a-button size="small" type="primary" shape="circle" @click="openClassificationModal">
                  <template #icon>
                    <PlusOutlined/>
                  </template>
                </a-button>
              </div>
              <a-divider orientation="right">标签</a-divider>
              <div class="post_popover_content_row">
                <a-select mode="multiple" v-model:value="blog.tagIdList">
                  <a-select-option v-for="tag in tagOptions" :key="tag.id">
                    {{ tag.name }}
                  </a-select-option>
                </a-select>
                <a-button size="small" type="primary" shape="circle" @click="openTagModal">
                  <template #icon>
                    <PlusOutlined/>
                  </template>
                </a-button>
              </div>
              <a-divider orientation="right">简介</a-divider>
              <a-textarea v-model:value="blog.summary" :rows="5" :maxlength="500" showCount>
              </a-textarea>
              <div class="post_popover_content_row post_popover_content_commit">
                <a-button type="primary" @click.stop="commitBlog">确认发布</a-button>
              </div>
            </div>
          </template>
          <a-button type="primary" size="large">发布</a-button>
        </a-popover>
      </div>
      <!-- 主体部分 -->
      <div class="blog_edit_content">
        <div class="blog_content">
          <div class="blog_content_header">
            <div class="header_left">
              <a-upload accept="image/*" action="/api/file/upload/image"
                        :show-upload-list="false" v-model:file-list="imageList" @change="uploadImage">
                <div class="header_icon_box">
                  <a-tooltip title="插入图片">
                    <PictureOutlined/>
                  </a-tooltip>
                </div>
              </a-upload>
              <a-popover trigger="click" placement="bottomLeft">
                <template #title>
                  <div style="display: flex;justify-content: space-between">
                    <span>插入视频</span>
                    <a-tooltip title="哔哩哔哩网页端->点击分享按钮->复制嵌入代码->粘贴确认">
                      <a>说明</a>
                    </a-tooltip>
                  </div>
                </template>
                <template #content>
                  <a-space>
                    <a-input v-model:value="videoValue" placeholder="粘贴哔哩哔哩视频嵌入代码..." style="width: 240px"/>
                    <a-button type="primary" @click="uploadVideo">确认</a-button>
                  </a-space>
                </template>
                <div class="header_icon_box">
                  <a-tooltip title="插入视频">
                    <VideoCameraOutlined/>
                  </a-tooltip>
                </div>
              </a-popover>
            </div>
            <div class="header_right">
              <div class="header_icon_box" :class="{icon_select:editWidth===100}" @click.stop="editWidth=100">
                <a-tooltip>
                  <template #title>源代码模式</template>
                  <CodeOutlined/>
                </a-tooltip>
              </div>
              <div class="header_icon_box" :class="{icon_select:editWidth===50}" @click.stop="editWidth=50">
                <a-tooltip>
                  <template #title>1:1模式</template>
                  <OneToOneOutlined/>
                </a-tooltip>
              </div>
              <div class="header_icon_box" :class="{icon_select:editWidth===0}" @click.stop="editWidth=0">
                <a-tooltip>
                  <template #title>预览模式</template>
                  <ProfileOutlined/>
                </a-tooltip>
              </div>
              <div class="header_icon_box" @click.stop="exportMarkDown">
                <a-tooltip>
                  <template #title>导出</template>
                  <FileMarkdownOutlined/>
                </a-tooltip>
              </div>
            </div>
          </div>
          <div class="blog_content_box">
            <a-textarea ref="edit_textarea" class="blog_content_edit" v-model:value="blog.content"
                        v-show="editWidth !== 0"
                        :style="{width:editWidth+'%'}" placeholder="输入博客正文..." auto-size/>
            <div class="blog_content_show" v-show="editWidth !== 100" :style="{width:100-editWidth+'%'}">
              <markdown :content='blog.content'/>
            </div>
          </div>
        </div>
      </div>
      <!-- 分类弹窗 -->
      <a-modal v-model:visible="classificationModalVisible" title="添加分类" @ok="addClassification"
               okText="添加" cancelText="取消">
        <a-input v-model:value="classificationName" placeholder="请输入分类名称" :maxlength="20" showCount/>
      </a-modal>
      <!-- 标签弹窗 -->
      <a-modal v-model:visible="tagModalVisible" title="添加标签" @ok="addTag"
               okText="添加" cancelText="取消">
        <a-input v-model:value="tagName" placeholder="请输入标签名称" :maxlength="20" showCount/>
      </a-modal>
    </div>
  </a-spin>
</template>

<script>
import { defineComponent, getCurrentInstance, onMounted, reactive, toRefs } from 'vue'
import Markdown from '@/components/markdown/Markdown'
import {
  CodeOutlined,
  FileMarkdownOutlined,
  OneToOneOutlined,
  PictureOutlined,
  PlusOutlined,
  ProfileOutlined,
  VideoCameraOutlined
} from '@ant-design/icons-vue'
import {
  AddBlog,
  AddClassification,
  AddTag,
  GetBlogDetailForUpdate,
  GetClassificationList,
  GetTagList,
  UpdateBlog
} from '@/service/blog'
import { useRoute, useRouter } from 'vue-router'

export default defineComponent({
  setup () {
    const { proxy } = getCurrentInstance()
    const route = useRoute()
    const router = useRouter()
    const state = reactive({
      loading: true,
      showToc: true,
      editWidth: 50,
      blogId: route.query.id,
      blog: {
        id: '',
        title: '',
        classificationId: '',
        tagIdList: [],
        summary: '',
        content: ''
      },
      classificationOptions: [],
      tagOptions: [],
      classificationModalVisible: false,
      classificationName: '',
      tagModalVisible: false,
      tagName: '',
      postPopoverVisible: false,
      imageList: [],
      videoValue: ''
    })

    const methods = reactive({
      openClassificationModal: () => {
        state.classificationModalVisible = true
        state.postPopoverVisible = false
      },
      openTagModal: () => {
        state.tagModalVisible = true
        state.postPopoverVisible = false
      },
      uploadImage: info => {
        if (info.file.status === 'done') {
          const {
            isSuccess,
            resultData,
            resultMsg
          } = info.file.response
          if (isSuccess) {
            state.blog.content += `\n![${info.file.name}](${resultData})\n`
            proxy.$message.success('上传图片成功！')
          } else {
            proxy.$message.error(resultMsg)
          }
        }
      },
      uploadVideo: () => {
        if (state.videoValue.trim().length === 0) {
          proxy.$message.warning('无效视频代码！')
          return
        }
        state.blog.content += `\n${state.videoValue}\n`
        state.videoValue = ''
      },
      exportMarkDown: () => {
        const element = document.createElement('a')
        element.download = state.blog.title.trim() === '' ? '无标题.md' : state.blog.title.trim() + '.md'
        element.style.display = 'none'
        const blob = new Blob([state.blog.content])
        element.href = URL.createObjectURL(blob)
        document.body.appendChild(element)
        element.click()
        document.body.removeChild(element)
      },
      back: () => {
        router.back()
      },
      addClassification: async () => {
        if (state.classificationName.trim().length === 0) {
          proxy.$message.warning('请填写分类名称！')
          return
        }
        state.classificationModalVisible = false
        await AddClassification(state.classificationName)
        proxy.$message.success(`添加分类[${state.classificationName}]成功！`)
        state.classificationOptions = await GetClassificationList()
        state.classificationName = ''
      },
      addTag: async () => {
        if (state.tagName.trim().length === 0) {
          proxy.$message.warning('请填写标签名称！')
          return
        }
        state.tagModalVisible = false
        await AddTag(state.tagName)
        proxy.$message.success(`添加标签[${state.tagName}]成功！`)
        state.tagOptions = await GetTagList()
        state.tagName = ''
      },
      commitBlog: async () => {
        if (state.blog.title.trim().length === 0) {
          proxy.$message.warning('请填写博客标题！')
          return
        }
        if (state.blog.classificationId.length === 0) {
          proxy.$message.warning('请选择博客分类！')
          return
        }
        if (state.blog.summary.trim().length === 0) {
          proxy.$message.warning('请填写博客摘要！')
          return
        }
        if (state.blog.content.trim().length === 0) {
          proxy.$message.warning('请填写博客正文！')
          return
        }
        let blogId = state.blogId
        if (state.blogId) {
          await UpdateBlog(state.blog)
        } else {
          blogId = await AddBlog(state.blog)
        }
        proxy.$message.success('发布成功！')
        await router.push(`/blog/${blogId}`)
      }
    })

    onMounted(async () => {
      // 如果存在博客ID，
      if (state.blogId) {
        // 查询博客详情
        state.blog = await GetBlogDetailForUpdate(state.blogId)
      }
      // 查询分类和标签信息
      state.classificationOptions = await GetClassificationList()
      state.tagOptions = await GetTagList()
      // 关闭加载动画
      state.loading = false
    })

    return {
      ...toRefs(state),
      ...toRefs(methods)
    }
  },
  components: {
    Markdown,
    CodeOutlined,
    OneToOneOutlined,
    ProfileOutlined,
    PlusOutlined,
    FileMarkdownOutlined,
    PictureOutlined,
    VideoCameraOutlined
  }
})
</script>

<style lang="less" scoped>
.blog_edit_div {
  width: 100%;
  background-color: white;
  display: flex;
  flex-direction: column;

  & .edit_header {
    height: 64px;
    padding: 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;

    & .ant-input {
      width: 88%;
      border-color: #00000000;
      box-shadow: 0 0 0 0;
      font-size: 24px;
      font-weight: 500;
    }
  }

  & .blog_edit_content {
    display: flex;
    flex-direction: column;

    & .blog_content {
      display: flex;
      flex-direction: column;

      & .blog_content_header {
        width: 100%;
        height: 40px;
        font-size: 18px;
        padding: 0 20px;
        border: 1px solid #00000020;
        display: flex;
        align-items: center;
        justify-content: space-between;

        & .header_left, & .header_right {
          display: flex;
        }

        & .header_icon_box {
          margin: 0 5px;
          width: 25px;
          height: 25px;
          font-size: initial;
          display: flex;
          align-items: center;
          justify-content: center;
          cursor: pointer;

          &:hover {
            background-color: #00000030;
          }
        }

        & .icon_select {
          background-color: #00000030;
        }
      }

      & .blog_content_box {
        width: 100%;
        height: 100%;
        min-height: 500px;
        display: flex;
        border: 1px solid #00000020;
        border-top: 0;

        & .blog_content_edit {
          min-height: calc(100vh - 105px);
          padding: 20px 40px;
          border-color: #00000000;
          box-shadow: 0 0 0 0;
        }

        & .blog_content_show {
          width: 100%;
          min-height: calc(100vh - 105px);
          padding: 20px 40px;
          border-left: 1px solid #00000020;
        }
      }
    }
  }
}

& .post_popover_title {
  font-size: 20px;
  font-weight: 700;
  color: #00000090;
  line-height: 2.5;
}

& .post_popover_content {
  width: 400px;

  & .post_popover_content_row {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;

    & .ant-select {
      width: 90%;
    }
  }

  & .post_popover_content_commit {
    margin-top: 20px;
    justify-content: flex-end;
  }
}

.blog_toc_box {
  width: 15%;
  border-left: 1px solid #00000020;
  background-color: #fff;
  font-size: 14px;

  & .blog_toc_title {
    width: 100%;
    padding: 10px;
    border-bottom: 1px solid #00000010;
  }

  #blog_toc {
    width: 100%;
    white-space: nowrap;
    overflow-x: hidden;
    text-overflow: ellipsis;
    margin-top: 15px;
    margin-left: -10px;
  }
}

</style>
